type Color
    opaque
    (Number,Number,Number,Number);

export function Color:
    & { h: Number, s: Number, l: Number, a: Number } => Color
    default { s: 255, l: 127, a: 100 }
    & { h, s, l, a } =>
        let clamp := { |.[&(Number,Number) => Number]| &(n,m) =>
            if (n <= m): n,
            else: m
        },
        { |Color| (
            { clamp (h,359) },
            { clamp (s,255) },
            { clamp (l,255) },
            { clamp (a,100) }
        ) };

export method Color.hsla:
    (Number,Number,Number,Number)
    &(hsla) => hsla;

export method Color.css-value:
    String
    &(h,s,l,a) =>
        let (h,s,l,a) := (
            h.{String},
            { !!! (s.{Float} / 255.0) }.{String%0},
            { !!! (l.{Float} / 255.0) }.{String%0},
            { "?%" a.{String} }
        ),
        { "hsla(?, ?, ?, ?)" (h, s, l, a) };

export const White: Color
    { Color { h: 0, s: 0, l: 100 } };

export const Black: Color
    { Color { h: 0, s: 0, l: 0 } };
